//package com.hui.qiniucloud.service;
//
//import com.hui.qiniucloud.config.TtsProperties;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Service;
//import org.springframework.web.reactive.function.client.WebClient;
//import reactor.core.publisher.Mono;
//
//import java.util.Map;
//
//@Slf4j
//@Service
//public class TtsService {
//
//    @Autowired
//    private TtsProperties ttsProperties;
//
//    private final WebClient webClient;
//
//    public TtsService() {
//        this.webClient = WebClient.builder()
//                .baseUrl("https://openspeech.bytedance.com")
//                .build();
//    }
//
//    public Mono<byte[]> synthesizeSpeech(String text, String voiceType) {
//        Map<String, Object> request = Map.of(
//            "app", Map.of(
//                "appid", ttsProperties.getAppId(),
//                "token", "token123",
//                "cluster", "volcano_tts"
//            ),
//            "user", Map.of(
//                "uid", "uid123"
//            ),
//            "audio", Map.of(
//                "voice_type", voiceType != null ? voiceType : ttsProperties.getVoiceType(),
//                "encoding", "mp3",
//                "compression_rate", 1,
//                "rate", 24000,
//                "speed_ratio", 1.0,
//                "volume_ratio", 1.0,
//                "pitch_ratio", 1.0,
//                "emotion", "happy",
//                "language", "cn"
//            ),
//            "request", Map.of(
//                "reqid", java.util.UUID.randomUUID().toString(),
//                "text", text,
//                "text_type", "plain",
//                "operation", "query",
//                "silence_duration", "125",
//                "with_frontend", "1",
//                "frontend_type", "unitTson",
//                "pure_english_opt", "1"
//            )
//        );
//
//        return webClient.post()
//                .uri("/api/v1/tts")
//                .header("Content-Type", "application/json")
//                .header("Authorization", "Bearer;" + ttsProperties.getToken())
//                .bodyValue(request)
//                .retrieve()
//                .bodyToMono(byte[].class)
//                .doOnNext(bytes -> log.info("synthesizeSpeech response: {}", new String(bytes)))
//                        .doOnError(error -> log.error("synthesizeSpeech error: {}", error.getMessage()));
//    }
//}

package com.hui.qiniucloud.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hui.qiniucloud.config.TtsProperties;
import com.hui.qiniucloud.service.ITtsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
public class TtsService implements ITtsService {

    @Autowired
    private TtsProperties ttsProperties;

    @Autowired
    private ObjectMapper objectMapper; // 注入ObjectMapper用于日志打印

    private final WebClient webClient;
    // 构造函数中初始化 WebClient（带自定义缓冲区配置）
    public TtsService() {
        // 1. 定义缓冲区大小：这里设置为 10MB（10 * 1024 * 1024 字节），可根据实际需求调整
        int maxBufferSize = 10 * 1024 * 1024;

        // 2. 创建自定义的 ExchangeStrategies，设置更大的缓冲区
        ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder()
                .codecs(configurer -> {
                    // 配置 JSON 编解码器（保留原有功能）
                    configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder());
                    configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder());
                    // 🌟 核心配置：增大默认缓冲区大小
                    configurer.defaultCodecs().maxInMemorySize(maxBufferSize);
                })
                .build();

        // 3. 使用自定义的 ExchangeStrategies 构建 WebClient
        this.webClient = WebClient.builder()
                .baseUrl("https://openspeech.bytedance.com")
                .exchangeStrategies(exchangeStrategies) // 应用自定义配置
                .build();
    }


    public Mono<byte[]> synthesizeSpeech(String text, String voiceType) {
        // 🌟 修正 1: 使用可变的 HashMap 代替不可变的 Map.of()
        Map<String, Object> request = new HashMap<>();

        Map<String, Object> app = new HashMap<>();
        app.put("appid", ttsProperties.getAppId());
        app.put("token", ttsProperties.getToken()); // 从配置中获取token
        app.put("cluster", "volcano_tts"); // 注意：文档中是 vol**c**ano_tts
        request.put("app", app);

        Map<String, Object> user = new HashMap<>();
        user.put("uid", "uid123");
        request.put("user", user);

        Map<String, Object> audio = new HashMap<>();
        audio.put("voice_type", voiceType);
        audio.put("encoding", "mp3");
        audio.put("compression_rate", 1);
        audio.put("rate", 24000);
        audio.put("speed_ratio", 1.0);
        audio.put("volume_ratio", 1.0);
        audio.put("pitch_ratio", 1.0);
        audio.put("emotion", "happy");
        audio.put("explicit_language", "zh");
        request.put("audio", audio);

        Map<String, Object> req = new HashMap<>();
        req.put("reqid", UUID.randomUUID().toString());
        req.put("text", text);
        req.put("text_type", "plain");
        req.put("operation", "query");
        req.put("silence_duration", "125"); // "125ms" 字符串可能是正确的，取决于API文档
        // 🌟 修正 2: 将字符串数字改为 Integer 类型
        req.put("with_frontend", 1);
        req.put("frontend_type", "unitTson");
        req.put("pure_english_opt", 1);
        request.put("request", req);

        // 🌟 新增：打印最终将要发送的JSON字符串，方便调试
        try {
            String requestJson = objectMapper.writeValueAsString(request);
            log.info("Sending TTS Request JSON: {}", requestJson);
        } catch (JsonProcessingException e) {
            log.error("Failed to serialize TTS request to JSON", e);
        }

        return webClient.post()
                .uri("/api/v1/tts")
                .header("Content-Type", "application/json")
                // 确认：根据文档，Authorization Header 使用分号是正确的
                .header("Authorization", "Bearer;" + ttsProperties.getToken())
                .bodyValue(request) // WebClient会使用内置的编码器（如Jackson）将Map序列化为JSON
                .retrieve()
                .bodyToMono(byte[].class)
                // 🌟 修正 3: 打印有意义的成功日志（如响应字节长度）
                .doOnNext(bytes -> log.info("TTS request successful, received {} bytes of audio data", bytes.length))
                .doOnError(error -> log.error("TTS request failed: {}", error.getMessage())); // 增加错误日志
    }
}